//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.warrior;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.warrior.api.service.RpcService;
import com.warrior.api.utils.Generator;
import com.warrior.api.vo.*;
import com.warrior.api.vo.account.Account;
import com.warrior.api.vo.action.Actions;
import com.warrior.api.vo.transaction.Transaction;
import com.warrior.api.vo.transaction.TransactionHistory;
import com.warrior.api.vo.transaction.push.Tx;
import com.warrior.api.vo.transaction.push.TxAction;
import com.warrior.api.vo.transaction.push.TxRequest;
import com.warrior.api.vo.transaction.push.TxSign;
import com.warrior.ese.Action;
import com.warrior.ese.DataParam;
import com.warrior.ese.DataType;
import com.warrior.ese.Ese;

import java.text.SimpleDateFormat;
import java.util.*;

public class EosRpcService {
    private final RpcService rpcService;
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

    public EosRpcService(String baseUrl) {
        this.dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        this.rpcService = (RpcService) Generator.createService(RpcService.class, baseUrl);
    }

    public ChainInfo getChainInfo() {
        return (ChainInfo)Generator.executeSync(this.rpcService.getChainInfo());
    }

    public Block getBlock(String blockNumberOrId) {
        return (Block)Generator.executeSync(this.rpcService.getBlock(Collections.singletonMap("block_num_or_id", blockNumberOrId)));
    }

    public Account getAccount(String account) {
        return (Account)Generator.executeSync(this.rpcService.getAccount(Collections.singletonMap("account_name", account)));
    }

    public TableRows getTableRows(TableRowsReq req) {
        return (TableRows)Generator.executeSync(this.rpcService.getTableRows(req));
    }

    public Transaction pushTransaction(String compression, Tx pushTransaction, String[] signatures) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        String mapJakcson = mapper.writeValueAsString(new TxRequest(compression, pushTransaction, signatures));
        System.out.println(mapJakcson);
        return (Transaction)Generator.executeSync(this.rpcService.pushTransaction(new TxRequest(compression, pushTransaction, signatures)));
    }

    public Actions getActions(String accountName, Integer pos, Integer offset) throws Exception {
        LinkedHashMap<String, Object> requestParameters = new LinkedHashMap(3);
        requestParameters.put("account_name", accountName);
        requestParameters.put("pos", pos);
        requestParameters.put("offset", offset);
        return (Actions)Generator.executeSync(this.rpcService.getActions(requestParameters));
    }

    public List<String> getCurrencyBalance(String code, String accountName, String symbol) {
        LinkedHashMap<String, String> requestParameters = new LinkedHashMap(3);
        requestParameters.put("code", code);
        requestParameters.put("account", accountName);
        requestParameters.put("symbol", symbol);
        return (List)Generator.executeSync(this.rpcService.getCurrencyBalance(requestParameters));
    }

    public Transaction pushTransaction(String tx) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        TxRequest txObj = (TxRequest)mapper.readValue(tx, TxRequest.class);
        return (Transaction)Generator.executeSync(this.rpcService.pushTransaction(txObj));
    }

    public SignParam getOfflineSignParams(Long exp) {
        SignParam params = new SignParam();
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        params.setChainId(info.getChainId());
        params.setHeadBlockTime(info.getHeadBlockTime());
        params.setLastIrreversibleBlockNum(info.getLastIrreversibleBlockNum());
        params.setRefBlockPrefix(block.getRefBlockPrefix());
        params.setExp(exp);
        return params;
    }

    public Transaction transfer(String pk, String contractAccount, String from, String to, String quantity, String memo) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        Map<String, Object> dataMap = new LinkedHashMap();
        dataMap.put("from", from);
        dataMap.put("to", to);
        dataMap.put("quantity", (new DataParam(quantity, DataType.asset, Action.transfer)).getValue());
        dataMap.put("memo", memo);
        TxAction action = new TxAction(from, contractAccount, "transfer", dataMap);
        actions.add(action);
        tx.setActions(actions);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String data = Ecc.parseTransferData(from, to, quantity, memo);
        action.setData(data);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, Long buyRam) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        tx.setActions(actions);
        Map<String, Object> createMap = new LinkedHashMap();
        createMap.put("creator", creator);
        createMap.put("name", newAccount);
        createMap.put("owner", owner);
        createMap.put("active", active);
        TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap);
        actions.add(createAction);
        Map<String, Object> buyMap = new LinkedHashMap();
        buyMap.put("payer", creator);
        buyMap.put("receiver", newAccount);
        buyMap.put("bytes", buyRam);
        TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap);
        actions.add(buyAction);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String accountData = Ese.parseAccountData(creator, newAccount, owner, active);
        createAction.setData(accountData);
        String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam);
        buyAction.setData(ramData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction createAccount(String pk, String creator, String newAccount, String owner, String active, Long buyRam, String stakeNetQuantity, String stakeCpuQuantity, Long transfer) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        tx.setActions(actions);
        Map<String, Object> createMap = new LinkedHashMap();
        createMap.put("creator", creator);
        createMap.put("name", newAccount);
        createMap.put("owner", owner);
        createMap.put("active", active);
        TxAction createAction = new TxAction(creator, "eosio", "newaccount", createMap);
        actions.add(createAction);
        Map<String, Object> buyMap = new LinkedHashMap();
        buyMap.put("payer", creator);
        buyMap.put("receiver", newAccount);
        buyMap.put("bytes", buyRam);
        TxAction buyAction = new TxAction(creator, "eosio", "buyrambytes", buyMap);
        actions.add(buyAction);
        Map<String, Object> delMap = new LinkedHashMap();
        delMap.put("from", creator);
        delMap.put("receiver", newAccount);
        delMap.put("stake_net_quantity", (new DataParam(stakeNetQuantity, DataType.asset, Action.delegate)).getValue());
        delMap.put("stake_cpu_quantity", (new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate)).getValue());
        delMap.put("transfer", transfer);
        TxAction delAction = new TxAction(creator, "eosio", "delegatebw", delMap);
        actions.add(delAction);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String accountData = Ese.parseAccountData(creator, newAccount, owner, active);
        createAction.setData(accountData);
        String ramData = Ese.parseBuyRamData(creator, newAccount, buyRam);
        buyAction.setData(ramData);
        String delData = Ese.parseDelegateData(creator, newAccount, stakeNetQuantity, stakeCpuQuantity, transfer.intValue());
        delAction.setData(delData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction voteproducer(String pk, String voter, String proxy, List<String> producers) throws Exception {
        Comparator<String> comparator = (h1, h2) -> {
            return h2.compareTo(h1);
        };
        producers.sort(comparator.reversed());
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        Map<String, Object> dataMap = new LinkedHashMap();
        dataMap.put("voter", voter);
        dataMap.put("proxy", proxy);
        dataMap.put("producers", producers);
        TxAction action = new TxAction(voter, "eosio", "voteproducer", dataMap);
        actions.add(action);
        tx.setActions(actions);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String data = Ecc.parseVoteProducerData(voter, proxy, producers);
        action.setData(data);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction close(String pk, String contract, String owner, String symbol) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        Map<String, Object> dataMap = new LinkedHashMap();
        dataMap.put("close-owner", owner);
        dataMap.put("close-symbol", (new DataParam(symbol, DataType.symbol, Action.close)).getValue());
        TxAction action = new TxAction(owner, contract, "close", dataMap);
        actions.add(action);
        tx.setActions(actions);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String data = Ecc.parseCloseData(owner, symbol);
        action.setData(data);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction delegatebw(String pk, String from, String receiver, String stakeNetQuantity, String stakeCpuQuantity, Long transfer) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(1000L);
        List<TxAction> actions = new ArrayList();
        tx.setActions(actions);
        Map<String, Object> delMap = new LinkedHashMap();
        delMap.put("from", from);
        delMap.put("receiver", receiver);
        delMap.put("stake_net_quantity", (new DataParam(stakeNetQuantity, DataType.asset, Action.delegate)).getValue());
        delMap.put("stake_cpu_quantity", (new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate)).getValue());
        delMap.put("transfer", transfer);
        TxAction delAction = new TxAction(from, "eosio", "delegatebw", delMap);
        actions.add(delAction);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String delData = Ese.parseDelegateData(from, receiver, stakeNetQuantity, stakeCpuQuantity, transfer.intValue());
        delAction.setData(delData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction unDelegatebw(String pk, String from, String receiver, String stakeNetQuantity, String stakeCpuQuantity ) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        tx.setActions(actions);
        Map<String, Object> delMap = new LinkedHashMap();
        delMap.put("from", from);
        delMap.put("receiver", receiver);
        delMap.put("unstake_net_quantity", (new DataParam(stakeNetQuantity, DataType.asset, Action.delegate)).getValue());
        delMap.put("unstake_cpu_quantity", (new DataParam(stakeCpuQuantity, DataType.asset, Action.delegate)).getValue());
        TxAction delAction = new TxAction(from, "eosio", "undelegatebw", delMap);
        actions.add(delAction);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String delData = Ese.parseUnDelegateData(from, receiver, stakeNetQuantity, stakeCpuQuantity );
        delAction.setData(delData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction buyRam(String pk, String payer, String receiver, Long buyRam) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        tx.setActions(actions);
        Map<String, Object> buyMap = new LinkedHashMap();
        buyMap.put("payer", payer);
        buyMap.put("receiver", receiver);
        buyMap.put("bytes", buyRam);
        TxAction buyAction = new TxAction(payer, "eosio", "buyrambytes", buyMap);
        actions.add(buyAction);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String ramData = Ese.parseBuyRamData(payer, receiver, buyRam);
        buyAction.setData(ramData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public Transaction sellRam(String pk, String account, Long sellRam) throws Exception {
        ChainInfo info = this.getChainInfo();
        Block block = this.getBlock(info.getLastIrreversibleBlockNum().toString());
        Tx tx = new Tx();
        tx.setExpiration(info.getHeadBlockTime().getTime() / 1000L + 60L);
        tx.setRef_block_num(info.getLastIrreversibleBlockNum());
        tx.setRef_block_prefix(block.getRefBlockPrefix());
        tx.setNet_usage_words(0L);
        tx.setMax_cpu_usage_ms(0L);
        tx.setDelay_sec(0L);
        List<TxAction> actions = new ArrayList();
        Map<String, Object> buyMap = new LinkedHashMap();
        buyMap.put("account", account);
        buyMap.put("bytes", sellRam);
        TxAction buyAction = new TxAction(account, "eosio", "sellram", buyMap);
        actions.add(buyAction);
        tx.setActions(actions);
        String sign = Ecc.signTransaction(pk, new TxSign(info.getChainId(), tx));
        String ramData = Ese.parseSellRamData(account, sellRam);
        buyAction.setData(ramData);
        tx.setExpiration(this.dateFormatter.format(new Date(1000L * Long.parseLong(tx.getExpiration().toString()))));
        return this.pushTransaction("none", tx, new String[]{sign});
    }

    public TransactionHistory getTransaction(String txid) throws Exception {
        LinkedHashMap<String, Object> requestParameters = new LinkedHashMap(3);
        requestParameters.put("id", txid);
        return (TransactionHistory)Generator.executeSync(this.rpcService.get_transaction(requestParameters));
    }
}
